﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ChurchData.Business;
using ChurchData.Utility;
using System.IO;

namespace ChurchData
{
    public partial class PeopleRelationsUC : UserControl
    {
        #region Fields / Properties
        private int PeoplePK { get; set; }

        #endregion Fields / Properties

        #region Constructor
        public PeopleRelationsUC()
        {
            InitializeComponent();
        }

        #endregion Constructor

        #region Load & Populate methods
        public void LoadPersonInfo(int peoplePK)
        {
            PeoplePK = peoplePK;
            this.RefreshHousehold();
            this.RefreshRelationships();
        }

        private void RefreshHousehold()
        {
            this.grdHousehold.DataSource = null;

            PeopleBO pBO = new PeopleBO();
            People drP = pBO.GetRecordByPK(PeoplePK);

            // If they have a household
            if (drP.HouseholdFK == null)
            {
                lblHouseholdNumber.Text = "None";
                btnAddHousehold.Text = "Join or Start Household";
            }
            else
            {
                // Show the household number
                lblHouseholdNumber.Text = drP.HouseholdFK.ToString();
                btnAddHousehold.Text = "Add to Household";

                // Grab all the active household members
                IEnumerable<People> householdMembers = drP.Household.Peoples;
                IEnumerable<People> onlyActive = from hm in householdMembers
                                                 where hm.ActiveInd == true
                                                 select hm;

                DataTable dt = new DataTable();
                dt.Columns.Add("PeoplePK", typeof(Int32));
                dt.Columns.Add("Full Name", typeof(String));
                dt.Columns.Add("Head of House", typeof(Boolean));

                foreach (People p in onlyActive)
                {
                    DataRow dr = dt.NewRow();
                    dr["PeoplePK"] = p.PeoplePK;
                    dr["Full Name"] = p.FirstName + " " + p.LastName;
                    dr["Head of House"] = (p.HeadOfHouseInd != null)? Convert.ToBoolean(p.HeadOfHouseInd) : false;
                    dt.Rows.Add(dr);
                }

                this.grdHousehold.DataSource = dt;
                this.grdHousehold.Columns["PeoplePK"].Visible = false;
            }

            this.grdHousehold.Refresh();
        }

        private void RefreshRelationships()
        {
            PeopleRelatedBO prBO = new PeopleRelatedBO();
            List<PeopleRelationshipDisplay> ds = prBO.GetListForDisplay(PeoplePK);

            grdRelatives.DataSource = ds;
            grdRelatives.Columns["PeoplePK"].Visible = false;
            grdRelatives.Columns["PeopleRelatedPK"].Visible = false;
        }
        #endregion Load & Populate methods

        #region Control Events
        private void grdRelatives_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1)
            {
                int peoplePK = (int)grdRelatives.Rows[e.RowIndex].Cells["PeoplePK"].Value;
                ((MainForm)((PeopleMain)this.ParentForm).MdiParent).OpenPeopleMain(peoplePK);
            }
        }

        private void grdHousehold_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1)
            {
                int peoplePK = (int)grdHousehold.Rows[e.RowIndex].Cells["PeoplePK"].Value;
                ((MainForm)((PeopleMain)this.ParentForm).MdiParent).OpenPeopleMain(peoplePK);
            }
        }

        private void btnAddRelative_Click(object sender, EventArgs e)
        {
            People drP = new PeopleBO().GetRecordByPK(this.PeoplePK);
            AddRelationshipDialog dlg = new AddRelationshipDialog(AddRelationshipDialog.AddDialogMode.Relationship, PeoplePK, drP.LastName, drP.FirstName);
            dlg.ShowDialog();
            this.RefreshRelationships();
        }

        private void btnRemoveRelative_Click(object sender, EventArgs e)
        {
            if (grdRelatives.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please select the relationship to remove");
                return;
            }

            if (DialogResult.Yes == MessageBox.Show("Are you sure?", "Confirm", MessageBoxButtons.YesNo))
            {
                PeopleRelatedBO prBO = new PeopleRelatedBO();
                prBO.RemoveRelationship(Convert.ToInt32(grdRelatives.SelectedRows[0].Cells["PeopleRelatedPK"].Value));
                this.RefreshRelationships();
            }
        }

        private void btnAddHousehold_Click(object sender, EventArgs e)
        {
            People drP = new PeopleBO().GetRecordByPK(this.PeoplePK);
            if (drP.HouseholdFK == null)
            {
                using (TwoQuestionDialog dialog = new TwoQuestionDialog("Join or start?", "Start new household", "Join existing", true))
                {
                    dialog.ShowDialog();
                    if (dialog.DialogResult == DialogResult.OK)
                    {
                        if (dialog.Button1Clicked)
                        {
                            Household drH = new HouseholdBO().AddRecord();
                            new PeopleBO().UpdateHousehold(this.PeoplePK, drH.HouseholdPK);
                            new HouseholdBO().UpdateHeadOfHousehold(drH.HouseholdPK, this.PeoplePK);
                        }
                        else if (dialog.Button2Clicked)
                        {
                            AddRelationshipDialog addDialog = new AddRelationshipDialog(AddRelationshipDialog.AddDialogMode.JoinHousehold, this.PeoplePK, drP.LastName, drP.FirstName);
                            addDialog.ShowDialog();
                        }

                        this.RefreshHousehold();
                    }
                }
            }
            else
            {
                AddRelationshipDialog dlg = new AddRelationshipDialog(AddRelationshipDialog.AddDialogMode.HouseholdMember, PeoplePK, drP.LastName, drP.FirstName);
                dlg.ShowDialog();

                // If they didn't find the person they were looking to add they had the option to
                // create a new person.  The dialog just captured that they opted for that.
                // We are handling it here though
                if (dlg.CreateNewPersonInHousehold)
                {
                    // Use the AddDialog to create the person
                    AddDialog dlgAdd = new AddDialog(dlg.FirstName, dlg.LastName);
                    dlgAdd.ShowDialog();

                    // If they didn't cancel
                    if (dlgAdd.DialogResult == DialogResult.OK)
                    {
                        // Add the newly created person to the current persons household
                        int? householdFK = drP.HouseholdFK;

                        // Now update the selected person to the same household
                        new PeopleBO().UpdateHousehold(dlgAdd.NewPeoplePK, householdFK);

                        ((MainForm)((PeopleMain)this.ParentForm).MdiParent).OpenPeopleMain(dlgAdd.NewPeoplePK);
                    }
                }

                this.RefreshHousehold();
            }
        }

        private void btnLeaveHousehold_Click(object sender, EventArgs e)
        {
            if (grdHousehold.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please select someone to remove");
                return;
            }

            if (DialogResult.Yes == MessageBox.Show("Are you sure?", "Confirm Action", MessageBoxButtons.YesNo))
            {
                int peopleFK = (int)grdHousehold.SelectedRows[0].Cells["PeoplePK"].Value;
                new PeopleBO().UpdateHousehold(peopleFK, null);
                this.RefreshHousehold();
            }
        }

        private void btnMakeHead_Click(object sender, EventArgs e)
        {
            People p = new PeopleBO().GetRecordByPK(this.PeoplePK);
            
            if (p.HouseholdFK == null)
            {
                MessageBox.Show("Start by creating a new household\nor adding this person to an existing one.");
                return;
            }

            if (grdHousehold.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please select a person to make head of household");
                return;
            }

            int peopleFK = (int)grdHousehold.SelectedRows[0].Cells["PeoplePK"].Value;
            new HouseholdBO().UpdateHeadOfHousehold(Convert.ToInt32(p.HouseholdFK), peopleFK);

            this.RefreshHousehold();
        }

        private void btnImage_Click(object sender, EventArgs e)
        {
            HouseholdBO hBO = new HouseholdBO();
            People p = new PeopleBO().GetRecordByPK(this.PeoplePK);
            if (p.HouseholdFK == null)
            {
                MessageBox.Show("This person is not yet in a household.  Please start there.");
                return;
            }

            OpenFileDialog dlg = new OpenFileDialog();
            DialogResult dlgResult = dlg.ShowDialog();

            if (dlg.CheckFileExists && dlgResult != DialogResult.Cancel)
            {
                Image newImage = null;
                try
                {
                    FileStream st = File.Open(dlg.FileName, FileMode.Open);
                    Image tmp = Image.FromStream(st);
                    Image img = (Image)tmp.Clone();
                    st.Close();

                    // There's a limit to how big of a file is really necessary.
                    if (img.Height > 1000 || img.Width > 1000)
                    {
                        // This is to "Prevent using images internal thumbnail"
                        img.RotateFlip(RotateFlipType.Rotate180FlipNone);
                        img.RotateFlip(RotateFlipType.Rotate180FlipNone);

                        int newWidth = 1000;
                        int newHeight = img.Height * newWidth / img.Width;
                        if (newHeight > 1000)
                        {
                            // Resize with height instead of width
                            newWidth = img.Width * 1000 / img.Height;
                            newHeight = 1000;
                        }

                        newImage = img.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
                    }
                    else
                        newImage = img;
                }
                catch (Exception exc)
                {
                    if (exc.Message.IndexOf("Parameter is not valid") > -1)
                    {
                        MessageBox.Show("Terribly sorry but an error occurred assigning that image.  The error suggests that the file is either an incompatible image type or not an image at all?");
                    }
                    else
                    {
                        MessageBox.Show("Terribly sorry but an error occurred assigning that image.  If the image is in a compressed or network folder please copy it to a local folder and try again.\n\nActual Error Message:\n" + exc.Message);
                    }
                }

                // Save the image to the database
                System.Data.Linq.Binary linqImage = null;
                if (newImage != null)
                {
                    // TODO: Figure out the image problems
                    MemoryStream ms = new MemoryStream();
                    newImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    linqImage = new System.Data.Linq.Binary(ms.ToArray());
                    hBO.UpdateFamilyPicture(Convert.ToInt32(p.HouseholdFK), linqImage);
                    picFamilyPortrait.BackgroundImage = newImage;
                }
            }
        }

        private void btnRemoveImage_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show("Are you sure?", "Confirm image removal", MessageBoxButtons.YesNo))
            {
                HouseholdBO hBO = new HouseholdBO();
                People p = new PeopleBO().GetRecordByPK(this.PeoplePK);
                if (p.HouseholdFK == null)
                {
                    MessageBox.Show("This person is not yet in a household.  Please start there.");
                    return;
                }

                hBO.UpdateFamilyPicture(Convert.ToInt32(p.HouseholdFK), null);
            }
        }

        #endregion Control Events
    }
}
